package io.ede.modules.ede.service.impl;

import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import io.ede.common.exception.RRException;
import io.ede.common.utils.FiiUtils;
import io.ede.common.utils.XmlParser;
import io.ede.modules.ede.dao.ProjectDao;
import io.ede.modules.ede.entity.ProjectEntity;
import io.swagger.models.auth.In;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.ede.common.utils.PageUtils;
import io.ede.common.utils.Query;

import io.ede.modules.ede.dao.GroupDao;
import io.ede.modules.ede.entity.GroupEntity;
import io.ede.modules.ede.service.GroupService;
import org.springframework.transaction.annotation.Transactional;


@Service("groupService")
public class GroupServiceImpl extends ServiceImpl<GroupDao, GroupEntity> implements GroupService {

    @Autowired
    private ProjectDao projectDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<GroupEntity> page = this.page(
                new Query<GroupEntity>().getPage(params),
                new QueryWrapper<GroupEntity>()
        );
        return new PageUtils(page);
    }

    /**
     * 添加动作组
     * @param params
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addGroup(Map<String, Object> params){
        // 1.查询工程
        ProjectEntity project = projectDao.selectById(params.get("id")+"");
        String fii = project.getFii();
        // 2.保存/修改动作组
        String newName = FiiUtils.createNewAction(fii);
        String groupXml = "<xml xmlns=\"http://www.w3.org/1999/xhtml\">"
                + "  <variables></variables>"
                + "</xml>";
        GroupEntity groupEntity = new GroupEntity();
        groupEntity.setProjectId(Integer.parseInt(params.get("id")+""));
        groupEntity.setName(newName);
        groupEntity.setXml(groupXml);
        groupEntity.setPy("Start()");
        groupEntity.setCreateTime(new Date());
        //查询动作组
        Map<String,Object> actionParam = new HashMap<>();
        actionParam.put("project_id",params.get("id"));
        actionParam.put("name",newName);
        List<GroupEntity> groupList = (List<GroupEntity>)this.listByMap(actionParam);
        //判断动作组是否存在
        if(groupList!=null && groupList.size()>0 ){
            GroupEntity _group = groupList.get(0);
            groupEntity.setId(_group.getId());
            this.updateById(groupEntity);
        }else{
            this.save(groupEntity);
        }
        // 3.修改工程fii文件内容
        String xml = FiiUtils.addGroup(fii,newName);
        project.setFii(xml);
        projectDao.updateById(project);
    }

    /**
     * 删除动作组
     * @param params
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delGroup(Map<String, Object> params){
        String actionname = (String)params.get("actionname");
        //1. 从DB中删除
        Map<String,Object> map = new HashMap<>();
        map.put("project_id",params.get("id"));
        map.put("name",actionname);
        this.removeByMap(map);
        //2. 从目录中删除
        //修改工程fii文件
        ProjectEntity project = projectDao.selectById(params.get("id")+"");
        String fii = project.getFii();
        try {
            SAXReader reader = new SAXReader();
            Document document;
            document = reader.read(new ByteArrayInputStream(fii.getBytes("utf-8")));
            //获取root(根)节点
            Element root = document.getRootElement();
            //删除动作组
            XmlParser.delElement(root,actionname);
            //删除无人机
            String attrVal = actionname + actionname.replace("动作组","无人机");
            XmlParser.deleteElementMohu(root,"ActionFlight","actionfname",attrVal);
            XmlParser.deleteElementMohu(root,"ActionFlightID","actionfid",attrVal);
            XmlParser.deleteElementMohu(root,"ActionFlightPosX","actionfX",attrVal);
            XmlParser.deleteElementMohu(root,"ActionFlightPosY","actionfY",attrVal);
            XmlParser.deleteElementMohu(root,"ActionFlightPosZ","actionfZ",attrVal);
            String xml = document.asXML();
            System.out.println(xml);
            project.setFii(xml);
            projectDao.updateById(project);
        }catch (Exception e){
            throw new RRException("fii解析出错");
        }
    }

    //添加无人机
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addFlight(Map<String, Object> params) {
        String method = params.get("method") + "";
        String actionname = params.get("actionname") + "";
        String x = params.get("x") + "";
        String y = params.get("y") + "";
        String z = params.get("z") + "";
        //查询工程
        ProjectEntity project = projectDao.selectById(params.get("id") + "");
        String fii = project.getFii();
        String l = project.getAreaL();
        String w = project.getAreaW();
        if(Integer.parseInt(x) - Integer.parseInt(l)>0) {
            throw new RRException("初始位置设置失败，请重新输入。");
        }
        if(Integer.parseInt(y) - Integer.parseInt(w)>0){
            throw new RRException("初始位置设置失败，请重新输入。");
        }
        //修改工程fii文件
        try {
            SAXReader reader = new SAXReader();
            Document document;
            byte[] fiiBytes = null;
            try {
                fiiBytes = fii.getBytes("utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            document = reader.read(new ByteArrayInputStream(fiiBytes));
            //获取root(根)节点
            Element root = document.getRootElement();
            String flight = actionname.replace("动作组", "无人机");
            //判断是否已经存在无人机，防止重复添加
            if("add".equals(method)) {
                List<Element> flightList = XmlParser.getNameElement(root, "ActionFlight");
                if (flightList != null && flightList.size() > 0) {
                    boolean flag = false;
                    for (Element one : flightList) {
                        String actionfname = XmlParser.attrValue(one, "actionfname");
                        if ((actionname + flight).equals(actionfname)) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag) {
                        throw new RRException("无人机已存在，无法添加！");
                    }
                }
                //判断无人机位置是否重叠
                List<Element> posXList = XmlParser.getNameElement(root, "ActionFlightPosX");
                List<Element> posYList = XmlParser.getNameElement(root, "ActionFlightPosY");
                if (posXList != null && posXList.size() > 0) {
                    boolean flag = false;
                    for (int i=0;i<posXList.size();i++) {
                        Element one = posXList.get(i);
                        Element two = posYList.get(i);
                        String actionfX = XmlParser.attrValue(one, "actionfX");
                        String actionfY = XmlParser.attrValue(two, "actionfY");
                        if (x.equals(actionfX.split("pos")[1]) && y.equals(actionfY.split("pos")[1])) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag) {
                        throw new RRException("初始位置上已有无人机存在，请重新输入！");
                    }
                }
                //添加无人机
                XmlParser.addElement(root, "ActionFlight", "actionfname", actionname + flight, "");
                //添加无人机编号
                String no = actionname.substring(actionname.length() - 1, actionname.length());
                XmlParser.addElement(root, "ActionFlightID", "actionfid", actionname + flight + "UAVID" + no + "001", "");
                //添加x坐标
                XmlParser.addElement(root, "ActionFlightPosX", "actionfX", actionname + flight + "pos" + x, "");
                //添加y坐标
                XmlParser.addElement(root, "ActionFlightPosY", "actionfY", actionname + flight + "pos" + y, "");
                //添加z坐标
                XmlParser.addElement(root, "ActionFlightPosZ", "actionfZ", actionname + flight + "pos" + z, "");

            }else if("upd".equals(method)){
                //判断无人机位置是否与其他无人机重叠
                List<Element> posXList = XmlParser.getNameElement(root, "ActionFlightPosX");
                List<Element> posYList = XmlParser.getNameElement(root, "ActionFlightPosY");
                if (posXList != null && posXList.size() > 0) {
                    boolean flag = false;
                    for (int i=0;i<posXList.size();i++) {
                        Element one = posXList.get(i);
                        Element two = posYList.get(i);
                        String actionfX = XmlParser.attrValue(one, "actionfX");
                        String actionfY = XmlParser.attrValue(two, "actionfY");
                        if (x.equals(actionfX.split("pos")[1]) && y.equals(actionfY.split("pos")[1]) && !actionfX.contains(actionname)) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag) {
                        throw new RRException("初始位置上已有无人机存在，请重新输入！");
                    }
                }
                //删除无人机
                String attrVal = actionname + actionname.replace("动作组","无人机");
                XmlParser.deleteElementMohu(root,"ActionFlightPosX","actionfX",attrVal);
                XmlParser.deleteElementMohu(root,"ActionFlightPosY","actionfY",attrVal);
                XmlParser.deleteElementMohu(root,"ActionFlightPosZ","actionfZ",attrVal);
                //添加x坐标
                XmlParser.addElement(root, "ActionFlightPosX", "actionfX", actionname + flight + "pos" + x, "");
                //添加y坐标
                XmlParser.addElement(root, "ActionFlightPosY", "actionfY", actionname + flight + "pos" + y, "");
                //添加z坐标
                XmlParser.addElement(root, "ActionFlightPosZ", "actionfZ", actionname + flight + "pos" + z, "");
            }

            String xml = document.asXML();
            System.out.println(xml);
            project.setFii(xml);
            projectDao.updateById(project);
        } catch (DocumentException e) {
            throw new RRException("fii解析出错");
        }

    }

    /**
     *  查询无人机
     * @param params
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String,String> getFlight(Map<String, Object> params) {
        Map<String,String> result = new HashMap<>();
        String actionname = params.get("actionname") + "";
        //查询工程
        ProjectEntity project = projectDao.selectById(params.get("id") + "");
        String fii = project.getFii();
        //修改工程fii文件
        try {
            SAXReader reader = new SAXReader();
            Document document;
            byte[] fiiBytes = null;
            try {
                fiiBytes = fii.getBytes("utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            document = reader.read(new ByteArrayInputStream(fiiBytes));
            //获取root(根)节点
            Element root = document.getRootElement();
            //判断无人机位置是否重叠
            List<Element> posXList = XmlParser.getNameElement(root, "ActionFlightPosX");
            List<Element> posYList = XmlParser.getNameElement(root, "ActionFlightPosY");
            if (posXList != null && posXList.size() > 0) {
                for (int i=0;i<posXList.size();i++) {
                    Element one = posXList.get(i);
                    Element two = posYList.get(i);
                    String actionfX = XmlParser.attrValue(one, "actionfX");
                    String actionfY = XmlParser.attrValue(two, "actionfY");
                    if(actionfX.contains(actionname)){
                        String x = actionfX.split("pos")[1];
                        String y = actionfY.split("pos")[1];
                        result.put("x",x);
                        result.put("y",y);
                        break;
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

}
